package icu.cocoon.work.controller;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.alibaba.excel.write.metadata.fill.FillWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import icu.cocoon.dao.base.BaseController;
import icu.cocoon.dao.base.Resp;
import icu.cocoon.mail.entity.Mail;
import icu.cocoon.mail.service.MailService;
import icu.cocoon.system.entity.Org;
import icu.cocoon.system.entity.User;
import icu.cocoon.system.service.OrgService;
import icu.cocoon.system.service.SecurityService;
import icu.cocoon.system.service.UserService;
import icu.cocoon.util.UUIDGenerator;
import icu.cocoon.work.entity.WeekContentItem;
import icu.cocoon.work.entity.WeekNextItem;
import icu.cocoon.work.entity.WeekReport;
import icu.cocoon.work.entity.excel.weekReport.ItemExcelData;
import icu.cocoon.work.entity.excel.weekReport.NextItemExcelData;
import icu.cocoon.work.entity.excel.weekReport.WeekReportExcelData;
import icu.cocoon.work.service.WeekContentItemService;
import icu.cocoon.work.service.WeekNextItemService;
import icu.cocoon.work.service.WeekReportService;
import io.jsonwebtoken.lang.Assert;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author Cocoon
 * @since 2020-06-12
 */
@Slf4j
@RestController
@RequestMapping("/work/weekReport")
public class WeekReportController extends BaseController<WeekReport, WeekReportService> {

  @Resource
  private SecurityService securityService;

  @Resource
  private UserService userService;

  @Resource
  private OrgService orgService;

  @Resource
  private WeekContentItemService weekContentItemService;

  @Resource
  private WeekNextItemService weekNextItemService;

  @Resource
  private MailService mailService;

  @Value("${excel.template-dir}")
  private String templateDir;
  @Value("${excel.temp-dir}")
  private String tempDir;

  @GetMapping("exportExcel/{id:\\d+}")
  public void export(@PathVariable Long id, HttpServletResponse response) throws IOException {
    WeekReport weekReport = getService().getById(id);
    if (weekReport == null) {
      return;
    }
    User user = userService.getById(weekReport.getUserId());
    Org org = orgService.getById(user.getOrgId());
    List<WeekContentItem> itemList = weekContentItemService.findByWeekReportId(weekReport.getId());
    List<WeekNextItem> nextItemList = weekNextItemService.findByWeekReportId(weekReport.getId());
    WeekReportExcelData excelData = new WeekReportExcelData();
    List<ItemExcelData> itemExcelDataList = itemList.stream().map(ItemExcelData::new).collect(Collectors.toList());
    List<NextItemExcelData> nextItemExcelDataList = nextItemList.stream().map(NextItemExcelData::new)
        .collect(Collectors.toList());
    excelData.setOrgName(org.getName());
    excelData.setUserName(user.getName());
    excelData.setStartDate(weekReport.getStartDate().toString());
    excelData.setEndDate(weekReport.getEndDate().toString());
    excelData.setNextStartDate(weekReport.getStartDate().plusDays(7).toString());
    excelData.setNextEndDate(weekReport.getEndDate().plusDays(7).toString());
    String template = templateDir + "week_report_template.xlsx";
    File templateFile = new File(template);
    log.info(templateFile.getAbsolutePath());
    log.info(templateFile.exists() + "");
    ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(templateFile).build();
    WriteSheet writeSheet = EasyExcel.writerSheet().build();
    FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();

    excelWriter.fill(excelData, writeSheet)
        .fill(new FillWrapper("list1", itemExcelDataList), fillConfig, writeSheet)
        .fill(new FillWrapper("list2", nextItemExcelDataList), fillConfig, writeSheet)
        .finish();

//    EasyExcel.write(response.getOutputStream()).withTemplate(template).sheet().doFill(excelData);
  }

  @PostMapping("sendMail/{id:\\d+}")
  public Resp<Mail> sendMail(@PathVariable Long id) {
    WeekReport weekReport = getService().getById(id);
    Assert.notNull(weekReport, "找不到指定的周报");
    String tmpFileName = UUIDGenerator.uuid();
    File file = new File(tempDir + tmpFileName + ".xlsx");

    User user = userService.getById(weekReport.getUserId());
    Org org = orgService.getById(user.getOrgId());
    List<WeekContentItem> itemList = weekContentItemService.findByWeekReportId(weekReport.getId());
    List<WeekNextItem> nextItemList = weekNextItemService.findByWeekReportId(weekReport.getId());
    WeekReportExcelData excelData = new WeekReportExcelData();
    List<ItemExcelData> itemExcelDataList = itemList.stream().map(ItemExcelData::new).collect(Collectors.toList());
    List<NextItemExcelData> nextItemExcelDataList = nextItemList.stream().map(NextItemExcelData::new)
        .collect(Collectors.toList());
    excelData.setOrgName(org.getName());
    excelData.setUserName(user.getName());
    excelData.setStartDate(weekReport.getStartDate().toString());
    excelData.setEndDate(weekReport.getEndDate().toString());
    excelData.setNextStartDate(weekReport.getStartDate().plusDays(7).toString());
    excelData.setNextEndDate(weekReport.getEndDate().plusDays(7).toString());
    String template = templateDir + "week_report_template.xlsx";
    ExcelWriter excelWriter = EasyExcel.write(file).withTemplate(template).build();
    WriteSheet writeSheet = EasyExcel.writerSheet().build();
    FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();

    excelWriter.fill(excelData, writeSheet)
        .fill(new FillWrapper("list1", itemExcelDataList), fillConfig, writeSheet)
        .fill(new FillWrapper("list2", nextItemExcelDataList), fillConfig, writeSheet)
        .finish();

    Mail mail = new Mail();
    String name = user.getName();
    String date = weekReport.getEndDate().toString();
    String title = name + date;

    Assert.isTrue(StringUtils.isNotBlank(user.getMailUsername()), "邮箱账号未输入，无法发送！！！");
    mail.setMailUsername(user.getMailUsername());
    Assert.isTrue(StringUtils.isNotBlank(user.getMailPassword()), "邮箱密码未输入，无法发送！！！");
    mail.setMailPassword(user.getMailPassword());

    mail.setToList(Collections.singletonList("pms@fagongzi.com"));
    mail.setCcList(Arrays.asList("gordon@fagongzi.com", "zt@fagongzi.com", "wb@fagongzi.com", "6631097@qq.com"));
    mail.setSubject(title + "-" + System.currentTimeMillis());
    mail.setContent(title);

    mailService.sendMail(mail, title + ".xlsx", file);
    if (!file.delete()) {
      log.error("文件" + file.getPath() + "删除失败");
    }
    return Resp.success(mail);
  }

  @Override
  public Resp<WeekReport> create(@RequestBody @Valid WeekReport model) {
    User user = securityService.getCurrentUser();
    Assert.notNull(user, "无法获取到当前用户,请联系管理员！");
    Assert.isTrue(model.getStartDate().compareTo(model.getEndDate()) < 0, "开始日期不可大于结束日期");
    model.setUserId(user.getId());
    return super.create(model);
  }

  @Override
  public Resp<WeekReport> update(@RequestBody @Valid WeekReport model) {
    Assert.isTrue(model.getStartDate().compareTo(model.getEndDate()) < 0, "开始日期不可大于结束日期");
    return super.update(model);
  }

  @Override
  protected QueryWrapper<WeekReport> getWrapper(Map<String, String> params) {
    QueryWrapper<WeekReport> wrapper = super.getWrapper(params);
    User user = securityService.getCurrentUser();
    Long userId = 0L;
    if (user != null) {
      userId = user.getId();
    }
    wrapper.lambda().eq(WeekReport::getUserId, userId);
    return wrapper;
  }
}

